package com.edu.hnu.gateway.components;

import com.alibaba.fastjson.JSON;
import com.edu.hnu.gateway.auth.JwtOperator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;


@Component
@RefreshScope
public class InternalURIAccessFilter implements GlobalFilter, Ordered {

    final JwtOperator jwtOperator;
    @Value("${allow.secret}")
    String allowSecret;

    @Value("${only-through-gateway}")
    boolean onlyThroughGateway;
    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    public InternalURIAccessFilter(JwtOperator jwtOperator) {
        this.jwtOperator = jwtOperator;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        ServerHttpRequest request = exchange.getRequest();

        //获取url
        String path = request.getURI().getPath();
        System.out.println(path);
        ServerHttpRequest.Builder reqBuilder = exchange.getRequest().mutate();
        //1. 放行swagger请求
        String[] excludePatterns = new String[]{"/**/swagger-resources/**", "/**/webjars/**", "/**/v2/**", "/**/swagger-ui.html/**", "/**/api-docs", "/**/api-docs/**", "/**/doc.html/**"};
        for (String pattern : excludePatterns) {
            if (antPathMatcher.match(pattern, path)) {
                return chain.filter(exchange.mutate().request(reqBuilder.build()).build());
            }
        }
        // 该配置是从nacos config中动态获取的
        if (onlyThroughGateway) {//如果要求只能通过网关访问服务
            reqBuilder.header("allow", allowSecret).build();
        }


        //返回值定义
        ServerHttpResponse response = exchange.getResponse();
        Map<String, Object> map = new HashMap<>();
        //2.禁止访问内部服务

        String[] bannedPatterns = new String[]{"/api/contract/interval/**", "/api/contract/ca/interval/**", "/api/user/feign/user-server/internal/**", ""};
        for (String pattern : bannedPatterns) {
            if (antPathMatcher.match(pattern, path)) {
                map.put("message", "内部服务无法访问");
                map.put("code", 10401);
                map.put("success", false);
                map.put("data", new Object());
                byte[] bytes = JSON.toJSONString(map).getBytes(StandardCharsets.UTF_8);
                DataBuffer buffer = response.bufferFactory().wrap(bytes);
                response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
                return response.writeWith(Mono.just(buffer));
            }
        }
        //3.开放服务和登录注册请求不验证token,放行
        String[] openPatterns = new String[]{"/api/contract/open/**", "/api/user/*/login","/api/user/*/register"};
        for (String pattern : openPatterns) {
            if (antPathMatcher.match(pattern, path)) {
                return chain.filter(exchange.mutate().request(reqBuilder.build()).build());
            }
        }

//        //4.其他请求请求验证token
//        //获取请求头中信息
//        String token = request.getHeaders().getFirst("token");
//        System.out.println(token);
//        // 解析token中携带的用户信息
//        try {
//
//            if (token == null ||!jwtOperator.isTokenValid(token)) {
//
//                map.put("message", "签名验证失败11");
//                map.put("code", 10401);
//                map.put("success", false);
//                map.put("data", null);
//                byte[] bytes = JSON.toJSONString(map).getBytes(StandardCharsets.UTF_8);
//                DataBuffer buffer = response.bufferFactory().wrap(bytes);
//                response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
//                return response.writeWith(Mono.just(buffer));
//            }
//
//        } catch (Exception e) {
//            map.clear();
//            map.put("message", "签名验证中发生错误,验证失败");
//            map.put("code", 10401);
//            map.put("success", false);
//            map.put("data", new Object());
//            byte[] bytes = JSON.toJSONString(map).getBytes(StandardCharsets.UTF_8);
//            DataBuffer buffer = response.bufferFactory().wrap(bytes);
//            response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
//            return response.writeWith(Mono.just(buffer));
//        }

        return chain.filter(exchange.mutate().request(reqBuilder.build()).build());


    }

    @Override
    public int getOrder() {
        return -100;
    }
}
